﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace OctopusWebInterface
{
    internal static class Functions
    {
        public static void SendUnknown(string userName, HttpRequest req, HttpResponse resp)
        {
            resp.StatusCode = 404;
            resp.Close();
        }

        public static void SendDenied(string userName, HttpRequest req, HttpResponse resp)
        {
            resp.StatusCode = 403;
            resp.Close();
        }

        public static void SendServiceUnavailable(string userName, HttpRequest req, HttpResponse resp)
        {
            resp.StatusCode = 503;
            resp.Close();
        }

        public static void SendError(string userName, HttpRequest req, HttpResponse resp, string error)
        {
            resp.StatusCode = 500;
            resp.Write(error);
            resp.Flush();
            resp.Close();
        }

        public static void GetUserVm(string userName, HttpRequest req, HttpResponse resp)
        {
            var allVm = Octopus.OctopusLib.Functions.getAllVm_byOwner(userName);
            var sb = new System.Text.StringBuilder();
            sb.Append("[ ");
            foreach (var vm in allVm)
            {
                var vmState = Octopus.OctopusLib.Functions.getVmStateByGuid(vm.OctopusGuid);
                string s = String.Format("\"{0}\",\"{1}\",\"{2}\",\"{3}\",\"{4}\",", (vm.OctopusGuid.ToString()), vm.HostName, vmState, vm.CpuCount, (vm.MemorySize / 1048576UL));
                sb.Append(s);
            }
            sb.Remove(sb.Length - 1, 1);   // remove the last ','
            sb.Append("]");
            resp.Write(sb.ToString());
            resp.Flush();
            resp.Close();
        }

        public static void GetVmStatus(string userName, HttpRequest req, HttpResponse resp)
        {
            string vmGuid = req.QueryString.Get("guid");
            if (vmGuid == null || vmGuid.Trim() == "")
            {
                SendUnknown(userName, req, resp);
                return;
            }

            Guid guid = new System.Guid(vmGuid);
            string vmState = Octopus.OctopusLib.Functions.getVmStateByGuid(guid);
            resp.Write(vmState);
            resp.Flush();
            resp.Close();
        }

        public static void GetUserMessages(string userName, HttpRequest req, HttpResponse resp)
        {
            var msgs = Octopus.OctopusLib.Functions.getMessages(userName);

            var messages = from m in msgs
                           orderby m.ID descending
                           select m;

            var sb = new System.Text.StringBuilder();
            sb.Append("<dl>");
            foreach (var msg in messages)
            {
                sb.Append("<dt class=\"MsgDate\">").Append(msg.Date.ToString());
                sb.Append("</dt>");
                sb.Append("<dd class=\"MsgText\">").Append(msg.Message);
                sb.Append("</dd>");
            }

            sb.Append("</dl>");
            resp.Write(sb.ToString());
            resp.Flush();
            resp.Close();
        }

        //cancellamiiiiiiiiiiiiiii
        public static void TestMigrationVm(string userName, HttpRequest req, HttpResponse resp)
        {
            //string vmGuid = req.QueryString.Get("guid");
            //if (vmGuid == null || vmGuid.Trim() == "")
            //{
            //    SendError(userName,req,resp,"Invalid param: guid");
            //    return;
            //}

            //Guid guid = new System.Guid(vmGuid);
            //Octopus.OctopusLib.Functions.migrateVmAsync(userName, guid);
            //resp.Flush();
            resp.Close();    
        }

        public static void deleteVm(string userName, HttpRequest req, HttpResponse resp)
        {
            string vmGuid = req.QueryString.Get("guid");
            if (vmGuid == null || vmGuid.Trim() == "")
            {
                SendError(userName, req, resp, "Invalid param: guid");
                return;
            }

            Guid guid = new System.Guid(vmGuid);
            Octopus.OctopusLib.Functions.deleteVmAsync(userName, guid);
            resp.Flush();
            resp.Close();
        }

        public static void cancelConfVm(string userName, HttpRequest req, HttpResponse resp)
        {
            string vmGuid = req.QueryString.Get("guid");
            if (vmGuid == null || vmGuid.Trim() == "")
            {
                SendError(userName, req, resp, "Invalid param: guid");
                return;
            }

            Guid guid = new System.Guid(vmGuid);
            Octopus.OctopusLib.Functions.turnoffVm(userName, guid);
            System.Threading.Thread.Sleep(1000);
            Octopus.OctopusLib.Functions.deleteVmAsync(userName, guid);
            resp.Flush();
            resp.Close();
        }

        public static void startVm(string userName, HttpRequest req, HttpResponse resp)
        {
            string vmGuid = req.QueryString.Get("guid");
            if (vmGuid == null || vmGuid.Trim() == "")
            {
                SendError(userName, req, resp, "Invalid param: guid");
                return;
            }

            Guid guid = new System.Guid(vmGuid);
            Octopus.OctopusLib.Functions.startVmAsync(userName, guid);
            resp.Flush();
            resp.Close();
        }

        public static void turnoffVm(string userName, HttpRequest req, HttpResponse resp)
        {
            string vmGuid = req.QueryString.Get("guid");
            if (vmGuid == null || vmGuid.Trim() == "")
            {
                SendError(userName, req, resp, "Invalid param: guid");
                return;
            }

            Guid guid = new System.Guid(vmGuid);
            Octopus.OctopusLib.Functions.turnoffVmAsync(userName, guid);
            resp.Flush();
            resp.Close();
        }

        public static void suspendVm(string userName, HttpRequest req, HttpResponse resp)
        {
            string vmGuid = req.QueryString.Get("guid");
            if (vmGuid == null || vmGuid.Trim() == "")
            {
                SendError(userName, req, resp, "Invalid param: guid");
                return;
            }

            Guid guid = new System.Guid(vmGuid);
            Octopus.OctopusLib.Functions.suspendVmAsync(userName, guid);
            resp.Flush();
            resp.Close();
        }

        public static void createNewVm(string userName, HttpRequest req, HttpResponse resp)
        {
            string numVm = req.QueryString.Get("numVm");
            string vmName = req.QueryString.Get("vmName");
            string hostName = req.QueryString.Get("hostName");
            string adminPass = req.QueryString.Get("adminPass");
            string cpuCores = req.QueryString.Get("cpuCores");
            string ramAmount = req.QueryString.Get("ramAmount");
            string templateId = req.QueryString.Get("templateId");

            if (numVm == null || numVm.Trim() == "")
                SendError(userName, req, resp, "Invalid param: numVm");
            else if (vmName == null || vmName.Trim() == "")
                SendError(userName, req, resp, "Invalid param: vmName");
            else if (hostName == null || hostName.Trim() == "")
                SendError(userName, req, resp, "Invalid param: hostName");
            else if (adminPass == null || adminPass.Trim() == "")
                SendError(userName, req, resp, "Invalid param: adminPass");
            else if (cpuCores == null || cpuCores.Trim() == "")
                SendError(userName, req, resp, "Invalid param: cpuCores");
            else if (ramAmount == null || ramAmount.Trim() == "")
                SendError(userName, req, resp, "Invalid param: ramAmount");
            else if (templateId == null || templateId.Trim() == "")
                SendError(userName, req, resp, "Invalid param: templateId");
            else
            {
                try
                {
                    var numVm_ = System.Int32.Parse(numVm);
                    var cpuCores_ = System.Int32.Parse(cpuCores);
                    var templateId_ = System.Int32.Parse(templateId);
                    var ramAmount_ = System.UInt64.Parse(ramAmount);
                    if (ramAmount_ % 2 != 0) ramAmount_++;

                    Guid vmGuid = Octopus.OctopusLib.Functions.createNewVm(userName, templateId_, numVm_, cpuCores_, ramAmount_, hostName, adminPass);
                    resp.Write(vmGuid.ToString());
                    resp.Flush();
                    resp.Close();
                }
                catch (Exception e)
                {
                    SendError(userName, req, resp, e.Message);
                }
            }
        }
    
    }


    public partial class GetAjax : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            this.Response.BufferOutput = true;
            this.Response.StatusCode = 200;
            this.Response.ContentType = "text/plain";
            this.Response.Cache.SetNoServerCaching();
            this.Response.Cache.SetNoStore();

            string userName;
            try { userName = this.LoginName1.Page.User.Identity.Name.Trim(); }
            catch { userName = null; }

            if (userName == null || userName == "")
            {
                Functions.SendDenied(userName, this.Request, this.Response);
                return;
            }

            string funcName = this.Request.QueryString.Get("func");
            try
            {
                switch (funcName)
                {
                    case "testMigrationVm": Functions.TestMigrationVm(userName, this.Request, this.Response); break;

                    case "getUserVm": Functions.GetUserVm(userName, this.Request, this.Response); break;
                    case "getVmStatus": Functions.GetVmStatus(userName, this.Request, this.Response); break;
                    case "getUserMessages": Functions.GetUserMessages(userName, this.Request, this.Response); break;
                    case "deleteVm": Functions.deleteVm(userName, this.Request, this.Response); break;
                    case "cancelConfVm": Functions.cancelConfVm(userName, this.Request, this.Response); break;
                    case "startVm": Functions.startVm(userName, this.Request, this.Response); break;
                    case "stopVm": Functions.turnoffVm(userName, this.Request, this.Response); break;
                    case "saveVm": Functions.suspendVm(userName, this.Request, this.Response); break;
                    case "createNewVm": Functions.createNewVm(userName, this.Request, this.Response); break;

                    default: Functions.SendUnknown(userName, this.Request, this.Response); break;
                }
            }
            catch
            {
                Functions.SendServiceUnavailable(userName, this.Request, this.Response);
                return;
            }       
        }
    }
}